<!--
 * @Descripttion: 
 * @Author: chendingfengmail@163.com
 * @version: 
 * @Date: 2021-06-22 14:53:03
 * @LastEditors: chendingfengmail@163.com
 * @LastEditTime: 2022-01-21 08:23:24
-->
<template>
  <div class="dd-file-upload"
       style="float:left">
    <el-upload action="fakeaction"
               ref="ddFileUpload"
               :on-change="handleOnChange"
               :accept="accept"
               list-type="picture-card"
               :file-list="fileList"
               :limit="fileLimit"
               :on-exceed="limitCheck"
               :on-preview="handlePictureCardPreview"
               :on-remove="handleRemoveFile"
               :http-request="actionUpload"
               :disabled="removeBtnDisable">
      <i class="el-icon-plus"></i>
    </el-upload>
    <el-image-viewer v-if="showImgViewer"
                     :on-close="closeImgViewer"
                     :url-list="imgPreviewList" />
  </div>
</template>

<script>
import ElImageViewer from "element-ui/packages/image/src/image-viewer";
export default {
  name: "dd-file-upload",
  components: {
    ElImageViewer
  },
  props: {
    // 是否只提供预览
    isPreview: {
      type: Boolean,
      default: () => {
        return false;
      },
    },
    // 限制上传文件的类型（文件后缀带小数点，多个类型以逗号隔开）
    accept: {
      type: String,
      default: () => {
        return ".jpg,.jpeg,.png,.JPG,.JPEG";
      },
    },
    // 限制上传文件的个数
    fileLimit: {
      type: Number,
      default: () => {
        return 6;
      },
    },
    // 文件列表
    fileList: {
      type: Array,
      default: () => {
        return [];
      },
    },
    /**
     * 执行上传的钩子
     * 返回一个 Promise 对象
     */
    uploadRequest: {
      type: Function,
      required: true,
      default: function (formData) {
        return null;
      },
    },

    /**
     * 删除文件的回调
     */
    onRemoveFile: {
      type: Function,
      default: function (file, fileList) {
        return null;
      },
    },
    /**
     * 文件状态改变时的钩子，添加文件、上传成功和上传失败时都会被调用
     */
    onChange: {
      type: Function,
      default: function (file, fileList) {
        return null;
      },
    }
  },
  data() {
    return {
      dialogImageUrl: "",
      imagePreviewVisible: false,
      removeBtnDisable: false,
      cacheFileNum: 0,
      // 显示图片查看器
      showImgViewer: false,
      // 查看大图列表
      imgPreviewList: [],

      slightlyFile: {},
    };
  },
  created() { },
  mounted() {
    this.setPreview(this.isPreview);
  },
  watch: {
    isPreview(val, oldVal) {
      this.setPreview(val);
    },
    cacheFileNum(val, oldVal) {
      if (val === this.fileLimit) {
        this.disableUploadBox(true);
      } else {
        this.disableUploadBox(false);
      }
    },
    fileList(val, oldVal) {
      this.cacheFileNum = val.length;
    },

  },
  methods: {
    // 设置图片是否可读模式
    setPreview(val) {
      let _this = this;
      if (val) {
        _this.removeBtnDisable = true;
        _this.$refs.ddFileUpload.$children[1].$el.style.display = "none";
      } else {
        _this.removeBtnDisable = false;
        // 判断是否等于限定数
        if(_this.fileLimit === _this.fileList.length) {
          _this.$refs.ddFileUpload.$children[1].$el.style.display = "none";
        } else {
          _this.$refs.ddFileUpload.$children[1].$el.style.display = "";
        }
      }
    },

    // 隐藏上传按钮
    disableUploadBox(isDisable) {
      if (!this.isPreview) {
        if (isDisable) {
          this.$refs.ddFileUpload.$children[1].$el.style.display = "none";
        } else {
          this.$refs.ddFileUpload.$children[1].$el.style.display = "";
        }
      }

    },

    handleOnChange(file, fileList) {
      this.onChange(file, fileList)
      this.slightlyFile = file;
      this.$refs.ddFileUpload.handleRemove(file); //删除缩略图
    },

    // 检查图片个数
    limitCheck() {
      this.$message({
        type: "warning",
        message: `最多可以上传 ${fileLimit} 张图片`,
      });
    },

    // 检查文件类型
    fileTypeCheck(file) {
      let fileTypes = this.accept.split(",");
      let fileType = file.name.substring(file.name.lastIndexOf("."));
      if (fileTypes.indexOf(fileType) != -1) {
        return false;
      }
      return true;
    },

    // 文件选择回调
    checkFile(file) {
      if (this.fileTypeCheck(file)) {
        this.$message.error(`只能上传 [${this.accept}] 格式的图片!`);
        this.$refs.ddFileUpload.handleRemove(file); //删除缩略图
        return false;
      }
      const fileSize = file.size / 1024 / 1024 < 10;
      if (!fileSize) {
        this.$message.error("上传文件大小不能超过 10MB!");
        this.$refs.ddFileUpload.handleRemove(file); //删除缩略图
        return false;
      }

      return true;
    },

    // 图片放大预览 可左右切换同一数组图片
    handlePictureCardPreview(file) {
      // 设置为第一张查看点击的图片
      let imgList = [];
      let index = this.fileList.findIndex(item => item.id == file.id)
      // 按照点击图片开始预览
      this.fileList.forEach((item, i) => {
        if(i >= index) {
          imgList.push(item.url);
        }
      })
      this.fileList.forEach((item, i) => {
        if(i < index) {
          imgList.push(item.url);
        }
      })
      this.imgPreviewList = imgList;
      this.showImgViewer = true;
    },
	
    // 关闭图片查看器
    closeImgViewer() {
      this.showImgViewer = false;
    },

    // 执行上传
    actionUpload(params) {
      let _this = this;
      if (!_this.checkFile(this.slightlyFile)) {
        return false;
      }

      let img = new Image();
      let loadFile = this.slightlyFile;
      img.src = loadFile.url;
      img.onload = function () {
        let upFormData = new FormData();
        upFormData.append("file", loadFile.raw);
        _this
          .uploadRequest(upFormData, "test")
          .then((res) => {
            _this.fileList.push({
              url: res.value.url,
            });
            _this.cacheFileNum++;
          })
          .catch((error) => {
            this.$refs.ddFileUpload.handleRemove(params.file); //删除缩略图
            this.deleteFileList(params.file);
          });
      }.bind(this);
    },

    // 删除已上传文件
    handleRemoveFile(file, fileList) {
      this.onRemoveFile(file, fileList);
      this.deleteFileList(file);
    },
    deleteFileList(file) {
      this.cacheFileNum--;
      for (var i = 0; i < this.fileList.length; i++) {
        if (this.fileList[i].uid == file.uid) {
          this.fileList.splice(i, 1);
        }
      }
    },

    beforeUpload(file) { },
  },
};
</script>
<style lang="scss">
.dd-file-upload {
  .el-upload-list__item.is-success .el-upload-list__item-status-label {
    display: none;
  }

  .el-upload-list--picture-card .el-upload-list__item-status-label {
    display: none !important;
  }
}

.el-image-viewer__wrapper {
  z-index: 99999 !important;
}
</style>
